/*
 * Copyright 2009 Eat Local Food, LLC
 * Copyright (c) 2007 osCommerce (this file was written after
 * code review of osCommerce).
 *
 * This file is part of gwtCommerce.
 *
 * gwtCommerce is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * gwtCommerce is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with gwtCommerce.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.elf.gwt.store.client.components;

import com.elf.gwt.common.client.access.RequestParameter;
import com.elf.gwt.common.client.components.CommonSimpleComponent;
import com.elf.gwt.common.client.model.CategoryModel;
import com.elf.gwt.common.client.model.ManufacturerModel;
import com.elf.gwt.common.client.model.ProductMetaModel;
import com.elf.gwt.common.client.model.ProductModel;
import com.elf.gwt.common.client.model.ProductReviewMetaModel;
import com.elf.gwt.common.client.model.ProductReviewModel;
import com.elf.gwt.common.client.utils.CommonUtils;
import com.elf.gwt.store.client.StoreComponentController;
import com.elf.gwt.store.client.utils.StoreUtils;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.InlineHTML;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.VerticalPanel;

/**
 *  
 */
public class CreateProductReviewComponent extends JSONServerComponent
{	
	public static final String EditReview = "EditReview";

	protected VerticalPanel bodyPanel;
	protected ProductMetaModel productMetaModel;
	protected ProductReviewMetaModel productReviewMetaModel;
	protected ProductReviewsComponent productReviewsComponent;

	protected Grid headingPanel;
	protected InlineHTML nameLabel;
	protected InlineHTML priceLabel;
	protected Image image;

	protected TextArea textArea;
	protected RadioButton oneStarButton;
	protected RadioButton twoStarButton;
	protected RadioButton threeStarButton;
	protected RadioButton fourStarButton;
	protected RadioButton fiveStarButton;
	protected InlineHTML warningLabel;
	protected String action = "";
	protected String completedAction = "";

	/**
	 * Constructor
	 */
	public CreateProductReviewComponent(StoreComponentController controller, String stylePrefix)
	{
		super(controller, stylePrefix, null, false);
		this.setupTimer();
		if (productReviewsComponent == null) productReviewsComponent = (ProductReviewsComponent)controller.getComponent("ProductReviewsComponent");
		bodyPanel = new VerticalPanel();
		bodyPanel.setWidth("100%");
		bodyPanel.addStyleName(getHandle() + "BodyPanel");

		//Name, Model and Price
		headingPanel = new Grid(1,2);
		headingPanel.addStyleName(getHandle() + "Heading");
		headingPanel.getCellFormatter().setHorizontalAlignment(0, 1, HasHorizontalAlignment.ALIGN_RIGHT);
		headingPanel.getCellFormatter().setVerticalAlignment(0, 0, HasVerticalAlignment.ALIGN_TOP);
		headingPanel.getCellFormatter().setVerticalAlignment(0, 1, HasVerticalAlignment.ALIGN_TOP);
		nameLabel = new InlineHTML();
		priceLabel = new InlineHTML();
		priceLabel.addStyleName(getHandle() + "Price");
		headingPanel.setWidget(0, 0, nameLabel);
		image = new Image();
		image.setStyleName(getHandle() + "Image");
		warningLabel = new InlineHTML();
		this.setLoginRequired(true);
	}

	public boolean updateFromHistoryParameters(String[] params)
	{
		if (!super.updateFromHistoryParameters(params)) return false;
		
		action = "";

		int productReviewId = productReviewsComponent.getProductReviewModel().getId();
		int productId = StoreComponentController.productComponent.getProductModel().getId();
		int categoryId = StoreComponentController.categoriesComponent.getCategoryModel().getId();
		int manufacturerId = StoreComponentController.manufacturersComponent.getManufacturerModel().getId();
		String from = ProductReviewModel.PRODUCT;

		try {
			productReviewId = Integer.parseInt(params[1]);
			productId = Integer.parseInt(params[2]);
			categoryId = Integer.parseInt(params[3]);
			manufacturerId = Integer.parseInt(params[4]);
			from = params[5];
		}
		catch (Exception e) {};

		if (!(from.equals(ProductReviewModel.PRODUCT) || from.equals(ProductReviewModel.PRODUCTREVIEWS)))
			from = ProductReviewModel.PRODUCT;

		productReviewsComponent.getProductReviewModel().setId(productReviewId);

		StoreComponentController.productComponent.getProductModel().update(categoryId, productId, "");

		CategoryModel cmodel = StoreComponentController.categoriesComponent.getCategoryModel(categoryId);
		StoreComponentController.categoriesComponent.getCategoryModel().update(cmodel);

		if (manufacturerId != StoreComponentController.manufacturersComponent.getManufacturerModel().getId())
		{
			ManufacturerModel mmodel = StoreComponentController.manufacturersComponent.getManufacturerModelById(manufacturerId);
			StoreComponentController.manufacturersComponent.getManufacturerModel().update(mmodel);
			StoreComponentController.manufacturersComponent.rebuild();
			storeController.getMultipleResultsComponent().addComponent(StoreComponentController.categoriesComponent);
		}
		productReviewsComponent.getProductReviewModel().setFrom(from);

		storeController.getMultipleResultsComponent().addComponent(this);

		//Don't look for new products
		CommonSimpleComponent alwaysAskComponent = controller.getComponent("NewProductsComponent", false);
		if (alwaysAskComponent != null) storeController.getMultipleResultsComponent().removeComponent(alwaysAskComponent);

		return true;
	}

	public void additionalRequestParameters()
	{
		super.additionalRequestParameters();
		ProductReviewModel productReviewModel = productReviewsComponent.getProductReviewModel();
		addRequestParameter(new RequestParameter("reviewId", productReviewModel.getId()));
		if (action.length() > 0)
		{
			addRequestParameter(new RequestParameter("action", action));
			addRequestParameter(new RequestParameter("reviewRating", productReviewModel.getRating()));
			addRequestParameter(new RequestParameter("reviewText", productReviewModel.getReviewText()));
		}
		completedAction=action;
		action = "";
	}

	protected void buildMetaModel(JSONObject jsonObject)
	{
		productMetaModel = new ProductMetaModel(jsonObject);
		productReviewMetaModel = new ProductReviewMetaModel(jsonObject);
	}

	protected void buildModel(JSONObject jsonObject)
	{
		ProductModel pmodel = new ProductModel(jsonObject, productMetaModel.getImageWidthMax(), productMetaModel.getImageHeightMax());
		StoreComponentController.productComponent.getProductModel().update(pmodel);

		ProductReviewModel prmodel = new ProductReviewModel(jsonObject);
		productReviewsComponent.getProductReviewModel().update(prmodel);
	}

	public void buildFromModel() throws Exception
	{
		bodyPanel.clear();
		ProductReviewModel productReviewModel = productReviewsComponent.getProductReviewModel();

		ProductModel productModel = StoreComponentController.productComponent.getProductModel();

		panel.setText(0, 0, productModel.getName());
		panel.setWidget(1, 0, bodyPanel);

		//Name, Model and Price
		nameLabel.setHTML("<span class=\"" + getHandle() + "Name" +"\">" + productModel.getName() + "</span>" +
				"<br/><span class=\"" + getHandle() + "Model" +"\">[" + productModel.getModel() + "]</span>");
		String price = CommonUtils.productPriceDisplay (StoreComponentController.currenciesComponent.getCurrencyModel(), productModel.getPrice(), productModel.getPrice(), productModel.getSpecialPrice());
		priceLabel.setHTML(price);
		headingPanel.setWidget(0, 1, priceLabel);

		Grid mainPanel = new Grid(1,2);
		mainPanel.setWidth("100%");
		mainPanel.getCellFormatter().setWidth(0, 0, "100%");
		mainPanel.getCellFormatter().setVerticalAlignment(0, 1, HasVerticalAlignment.ALIGN_TOP);
		mainPanel.getCellFormatter().setHorizontalAlignment(0, 1, HasHorizontalAlignment.ALIGN_CENTER);

		VerticalPanel leftPanel = new VerticalPanel();
		leftPanel.setWidth("100%");
		VerticalPanel leftTopPanel = new VerticalPanel();
		leftTopPanel.setWidth("100%");
		VerticalPanel leftBotPanel = new VerticalPanel();
		leftBotPanel.setWidth("100%");
		HorizontalPanel buttonPanel = new HorizontalPanel();
		buttonPanel.setWidth("100%");

		leftPanel.add(leftTopPanel);
		leftPanel.add(leftBotPanel);
		leftPanel.add(buttonPanel);

		mainPanel.setWidget(0, 0, leftPanel);

		image.setUrl(StoreUtils.getImageProductsDirectory() + productModel.getImage());
		String[] imageSize = productModel.getImageSize();
		image.setSize(imageSize[0], imageSize[1]);
		image.setTitle(productModel.getName());
		mainPanel.setWidget(0, 1, image);

		bodyPanel.add(headingPanel);
		bodyPanel.add(mainPanel);

		if (productReviewModel.getId() == 0 && completedAction.equals(EditReview))
		{
			leftTopPanel.add(new InlineHTML("&nbsp;<br/>Thank you for creating a review, click the Go Back button to return to the catalog."));
		}
		else {
			leftTopPanel.add(new InlineHTML("&nbsp;"));
			leftTopPanel.add(new InlineHTML("<strong>From: </strong>" + productReviewModel.getAccountName()));
			leftTopPanel.add(new InlineHTML("<strong>Your Review:</strong>"));
			
			textArea = new TextArea();
			textArea.setWidth("100%");
			textArea.setCharacterWidth(200);
			textArea.setVisibleLines(15);
			leftBotPanel.add(textArea);

			InlineHTML noteLabel = new InlineHTML("</strong><font color=\"red\">NOTE:</font> HTML is not translated!  Also, you must have already ordered this product to create a review.");
			leftBotPanel.add(noteLabel);
			leftBotPanel.setCellWidth(noteLabel, "100%");
			leftBotPanel.setCellHorizontalAlignment(noteLabel, HasHorizontalAlignment.ALIGN_RIGHT);

			oneStarButton = new RadioButton("rating", " ");
			twoStarButton = new RadioButton("rating", " ");
			threeStarButton = new RadioButton("rating", " ");
			fourStarButton = new RadioButton("rating", " ");
			fiveStarButton = new RadioButton("rating", " ");
			HorizontalPanel ratingPanel = new HorizontalPanel();
			//ratingPanel.setWidth("100%");
			ratingPanel.add(new InlineHTML("<strong>Rating: </strong><font color=\"red\">BAD</font>"));
			ratingPanel.add(oneStarButton);
			ratingPanel.add(twoStarButton);
			ratingPanel.add(threeStarButton);
			ratingPanel.add(fourStarButton);
			ratingPanel.add(fiveStarButton);
			ratingPanel.add(new InlineHTML("<font color=\"red\">GOOD</font>"));
			leftBotPanel.add(ratingPanel);
			leftBotPanel.add(new InlineHTML("&nbsp;"));

			Button editButton = new Button(controller.getCommonConstants().Continue(), 
					new ClickHandler() {
						public void onClick(ClickEvent event) {
							String warningText = "";
							ProductReviewModel productReviewModel = productReviewsComponent.getProductReviewModel();
							if (oneStarButton.getValue()) productReviewModel.setRating(1);
							else if (twoStarButton.getValue()) productReviewModel.setRating(2);
							else if (threeStarButton.getValue()) productReviewModel.setRating(3);
							else if (fourStarButton.getValue()) productReviewModel.setRating(4);
							else if (fiveStarButton.getValue()) productReviewModel.setRating(5);
							else 
								warningText = "Please select a rating";

							String reviewText = textArea.getText();
							if (reviewText == null || reviewText.length() < productReviewMetaModel.getReviewTextMin())
							{
								if (warningText.length() > 0) warningText += ", ";
								warningText += "Review must be more than " + productReviewMetaModel.getReviewTextMin() + " characters long.";
							}

							if (warningText.length() == 0)
							{
								productReviewModel.setReviewText(textArea.getText());
								action = EditReview;
								build(true);
							}
							else
							{
								Window.alert(warningText);
							}
						}}
			);
			buttonPanel.add(editButton);
		}

		Button cancelButton = new Button(controller.getCommonConstants().GoBack(),
				new ClickHandler() {
					public void onClick(ClickEvent event) {
						ProductReviewModel productReviewModel = productReviewsComponent.getProductReviewModel();
						ProductModel productModel = StoreComponentController.productComponent.getProductModel();
						if (productReviewModel.getFrom().equals(ProductReviewModel.PRODUCT))
						{
							onSelection("ProductComponent--" + productModel.getId() + "--" + productModel.getCategoryId()
									+ "--" + StoreComponentController.manufacturersComponent.getManufacturerModel().getId());
						}
						else if (productReviewModel.getFrom().equals(ProductReviewModel.PRODUCTREVIEWS))
						{
							onSelection("ProductReviewsComponent--" + productModel.getId() + "--" +productModel.getCategoryId()
									+ "--" + StoreComponentController.manufacturersComponent.getManufacturerModel().getId()
									+ "--" + productReviewModel.getOffset() + "--" + productReviewModel.getOrderby());
						}
					}}
		);
		buttonPanel.setWidth("100%");
		buttonPanel.add(cancelButton);
		buttonPanel.setCellHorizontalAlignment(cancelButton, HasHorizontalAlignment.ALIGN_RIGHT);
		buttonPanel.setCellWidth(cancelButton, "100%");

		if (productReviewModel.getId() < 0) {
			String warningText = "";
			if (productReviewModel.getId() == -10)
				warningText = "Review must be more than " + productReviewMetaModel.getReviewTextMin();
			else if (productReviewModel.getId() == -20)
				warningText = "We're sorry, you must have ordered this product previously to be able to create a review";
			else if (productReviewModel.getId() < 0)
				warningText = "Unknown Error";

			warningLabel.setHTML("<br/><br/><span class=\"WarningLabel\">" + warningText + "<span><br/>");

			bodyPanel.add(warningLabel);
		}
		completedAction = "";
		onBuilt();
	}
}
